<script lang="ts" setup>
import type { FileObject } from '@/types/api/public'
import upload from '@/request/upload'
import { useChooseImage, useChooseVideo, useConsole, useHideLoading, useLoading, useModal, useNav } from '@/utils'
import { to } from 'await-to-js'
import { find, omit } from 'lodash-es'
import mime from 'mime'
import { computed } from 'vue'

const props = withDefaults(defineProps<{
  fileList: FileObject[]
  editable: boolean
  columns: number
}>(), {
  fileList: () => [],
  editable: true,
  columns: 3,
})

const fileListComputed = computed(() => props.fileList.map(x => ({
  ...x,
  mimeType: getMimeTypeName(x.fileUrl),
})))

const mimeDict = [
  { prefix: 'image/', cn: '图片', en: 'image' },
  { prefix: 'video/', cn: '视频', en: 'video' },
]

async function handleChooseFile() {
  // #ifndef MP-KUAISHOU
  const { tapIndex } = await uni.showActionSheet({
    itemList: ['图片', '视频'],
  })
  if (tapIndex === -1) {
    return
  }
  const fileRes = await (() => {
    if (tapIndex === 0) {
      return useChooseImage({ count: 1 })
    }
    else {
      return useChooseVideo({
        // sourceType: ['album'],
      })
    }
  })()
  // #endif
  // #ifdef MP-KUAISHOU
  const fileRes = await (() => {
    return useChooseImage({ count: 1 })
  })()
  // #endif
  useConsole?.log('[fileRes]', fileRes)

  useLoading(true)
  const [err, res] = await to(
    upload({ filePath: fileRes[0] }),
  )
  useHideLoading()
  if (err) {
    return
  }

  props.fileList.push(res)
}

async function handleDelFileItem(index: number) {
  const { confirm } = await useModal({
    content: '删除该文件？',
    cancelText: '取消',
    confirmText: '删除',
  })
  if (confirm) {
    props.fileList.splice(index, 1)
  }
}

function getMimeTypeName(url: string) {
  const type = mime.getType(url) ?? 'null'
  const matchedType = find(mimeDict, (v, _k) => type?.startsWith(v.prefix))!
  return omit(matchedType, 'prefix')
}

function handlePreview(index: number) {
  const current = fileListComputed.value[index]
  if (current.mimeType.en === 'image') {
    const images = fileListComputed.value.filter(x => x.mimeType.en === 'image').map(x => x.fileUrl)
    uni.previewImage({
      urls: images,
      current: current.fileUrl,
    })
  }
  else if (current.mimeType.en === 'video') {
    useNav('/video-preview', {
      src: current.fileUrl,
    })
  }
}
</script>

<template>
  <view class="flex flex-col gap-y-7px">
    <view
      class="grid gap-10px"
      :style="{ 'grid-template-columns': `repeat(${columns}, 1fr)` }"
    >
      <template
        v-for="(file, i) in fileListComputed"
        :key="i"
      >
        <ui-aspect-ratio>
          <view class="relative h-full bg-gray-100">
            <view
              class="h-full w-full"
              @click="handlePreview(i)"
            >
              <image
                v-if="file.mimeType.en === 'image'"
                :src="file.fileUrl"
                class="h-full w-full"
                mode="aspectFill"
              ></image>
              <view
                v-if="file.mimeType.en === 'video'"
                class="relative h-full w-full"
              >
                <image
                  class="h-full w-full"
                  src="~@/static/video-cover.jpg"
                  mode="aspectFill"
                ></image>
                <view class="absolute top-0 h-full w-full flex">
                  <view class="text-theme-primary i-icon-park-outline:play m-a text-70px"></view>
                </view>
              </view>
            </view>

            <view
              v-if="editable"
              class="absolute right-0 top-0 h-44px w-44px flex bg-[red]"
              @click="handleDelFileItem(i)"
            >
              <view class="i-icon-park-outline:close m-a text-30px text-white"></view>
            </view>
          </view>
        </ui-aspect-ratio>
      </template>
      <ui-aspect-ratio v-if="editable">
        <view
          class="h-full flex bg-gray-100"
          @click="handleChooseFile"
        >
          <view class="i-icon-park-outline:plus m-a text-44px"></view>
        </view>
      </ui-aspect-ratio>
    </view>
  </view>
</template>

<style lang="less" scoped></style>
